#ifndef REMOTEIMAGEVIEW_H
#define REMOTEIMAGEVIEW_H

#include <map>
#include <vector>

#include <QGraphicsView>
#include <QTimer>
#include <QMutex>
#include <QHostInfo>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

#include "clienttransfer.h"
#include "timestamp.h"
#include "imageview.h"
#include "databuffer.h"
#include "searchablequeue.h"

typedef struct image_transfer_info{
    unsigned int timestamp;
    int size;
    int total_seq;
    int expect_seq;
}image_transfer_info_t;

class RemoteImageView : public ImageView
{
    Q_OBJECT
public:
    explicit RemoteImageView(QWidget *parent = 0);
    
signals:
    void imageTransferProgress(int progess);
    void changeDirection(int x, int y, int z);
    void imgRequest(unsigned int timestamp, int seq, int width, int height, int tran_state, int speed);
    void trackRequest(int timestamp, int x1, int y1, int x2, int y2);
    void ptzRequest(int x, int y, int z);
    void setTransferServer(QHostAddress addr, quint16 sync_port, quint16 info_port, quint16 data_port);
    void frameRate(int fps);
    void showSaveFolder(QString);
    void syncDelay(int delay);
    void changeBrightness(int b);
    void changeContrast(int c);
    void changeHue(int h);
    void changeSaturation(int s);
    void changeCamera(int b, int c, int h, int s, int r);
    void changeCameraRecord(int r);
    void syncBrightness(int b);
    void syncContrast(int c);
    void syncHue(int h);
    void syncSaturation(int s);
    void changePtzX(int x);
    void changePtzY(int y);
    void changePtzZ(int z);
    void changeImageTranSwitch(int s);
    void changeImageTranSpeed(int s);


public slots:
    void changeTargetDirection(int x, int y, int z);
    void transferState(int s);
    void recvResponse(QByteArray response);
    void recvImageData(QByteArray image_data);
    void reqestTimerAction();

    void setAddressString(QString addr);
    void setAddress();

    void statisticsTimer();
    void setSaveFolder();
    void setSaveState(int s);

    void syncTimerAction();
    void setBrightness(int b);
    void setContrast(int c);
    void setHue(int h);
    void setSaturation(int s);
    void setCameraProp();
    void setImageTranSpeed(int s);
protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
private:




    //for img
    void restructImg(cv::Mat &img, unsigned int ts);
    bool isOld(unsigned int ts);

    int m_img_width;
    int m_img_height;

    QTimer m_req_timer;

    //for Statistics
    int m_frame_cost;
    TimeStamp m_frame_ts;
    int m_frame_count;

#define STATISTICS_INTERVAL 500
    QTimer m_stat_timer;


    //fro track
    int m_ori_width;
    int m_ori_height;
    TimeStamp m_display_ts;
    QMutex m_display_mutex;
    bool m_mouse_pressed;
    bool m_display_new;
    cv::Point2i m_track_pt1;
    cv::Point2i m_track_pt2;
    bool m_show_selected;
    ClientTransfer m_transfer;

    TimeStamp m_track_ts;
    cv::Point2i m_track_ans_pt1;
    cv::Point2i m_track_ans_pt2;
    cv::Point2i m_track_center;

    //for address
    QString m_addr_str;
    QHostAddress m_addr;

    //for save

    void startSaveVideo();
    void stopSaveVideo();
    void saveImg2Video(cv::Mat img);
    QString m_save_folder;
    QString m_save_file;
    cv::VideoWriter m_save_writer;
    bool m_save_state;
    QMutex m_save_mutex;

    //for sync
    QTimer m_sync_timer;
    TimeStamp m_last_sync_ts;
    bool m_has_connection;

    //for camera
    int m_camera_brightness;
    int m_camera_contrast;
    int m_camera_hue;
    int m_camara_saturation;

    //for image
    QMutex m_img_info_mutex;
    SearchableQueue<unsigned int, image_transfer_info_t> m_img_info;
    QMutex m_img_data_mutex;
    DataBuffer m_img_data;
    TimeStamp m_last_img_ts;
    cv::Mat m_image;
    bool m_transfer_state;

};



#endif // REMOTEIMAGEVIEW_H
